package com.thinkcoder.service.impl;

import com.thinkcoder.mybatisplusconfig.BaseServiceImpl;
import com.thinkcoder.entity.UserHit;
import com.thinkcoder.model.enums.UserHitEnum;
import com.thinkcoder.service.ZsetService;
import com.thinkcoder.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;


import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service
public class ZsetSerivceImpl extends BaseServiceImpl<UserHit> implements ZsetService {

    @Autowired
    private RedisUtil redisUtil;

    public static final String USER_HIT_COUNT="USER_HIT_COUNT";

    @Override
    public void add(UserHit hit){
        //得出该key下全部集合元素
        Set<Object> objects = redisUtil.zReverseBank(USER_HIT_COUNT, 0, -1);

        if(redisUtil.zHasElement(objects,hit.getModuleCode())){
            //如果包含该元素则score加1
            redisUtil.zIncrementScore(USER_HIT_COUNT,hit.getModuleCode(),1);
        }else{
            //否则添加该元素
            redisUtil.zAdd(USER_HIT_COUNT,hit.getModuleCode(),1);
        }
    }

    //从redis中取出数据
    public List<UserHit> getUserHits(){
        Set<ZSetOperations.TypedTuple<Object>> typedTuples = redisUtil.zReverseRangeWithScore(USER_HIT_COUNT, 0, -1);
        List<UserHit> dataModuleHit = getDataModuleHit(typedTuples);
        return dataModuleHit;
    }

    //将redis的值转换为list形式
    private List<UserHit> getDataModuleHit(Set<ZSetOperations.TypedTuple<Object>> typedTuples){
        List<UserHit> hits = new ArrayList<>();
        for(ZSetOperations.TypedTuple tuple : typedTuples){
            UserHit hit = new UserHit();
            hit.setModuleCode((Integer) tuple.getValue());
            hit.setModuleName(UserHitEnum.getModelName((Integer) tuple.getValue()));
            hit.setModuleHitCount(tuple.getScore().longValue());
            hits.add(hit);
        }
        return hits;
    }

    //将缓存数据同步到数据库中
    public void addHit(){
        Set<ZSetOperations.TypedTuple<Object>> typedTuples = redisUtil.zReverseRangeWithScore(USER_HIT_COUNT, 0, -1);
        List<UserHit> dataModuleHit = getDataModuleHit(typedTuples);
        this.saveBatch(dataModuleHit);
    }
}
